/*
 * Copyright (c) 2018-2999 深圳市阿毛科技有限公司 All rights reserved.
 *
 * https://www.lamyz.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.lam.mall.api.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.lam.common.base.domain.Result;
import com.lam.common.context.TokenUtils;
import com.lam.common.exception.BusinessException;
import com.lam.common.utils.DateUtil;
import com.lam.common.utils.NumberUtil;
import com.lam.common.utils.StringUtils;
import com.lam.common.validate.ValidateUtil;
import com.lam.framework.operLog.annotation.Log;
import com.lam.mall.app.param.OrderParam;
import com.lam.mall.app.param.OrderShopParam;
import com.lam.mall.app.param.SubmitOrderParam;
import com.lam.mall.app.vo.OrderNumbersVo;
import com.lam.mall.app.vo.ShopCartItemDiscountVo;
import com.lam.mall.app.vo.ShopCartItemVo;
import com.lam.mall.app.vo.ShopCartOrderMergerVo;
import com.lam.mall.app.vo.ShopCartOrderVo;
import com.lam.mall.app.vo.ShopCartVo;
import com.lam.mall.app.vo.UserAddrVo;
import com.lam.mall.common.event.PreSubmitOrderEvent;
import com.lam.mall.entity.Order;
import com.lam.mall.entity.UserAddr;
import com.lam.mall.service.BasketService;
import com.lam.mall.service.OrderService;
import com.lam.mall.service.ProdSkuService;
import com.lam.mall.service.ProductService;
import com.lam.mall.service.UserAddrService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;

/**
 * @author lam
 */
@RestController
@RequestMapping("/${frontPath}/order")
@Log(title = "订单接口")
public class OrderApiController {
	
	 private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderService orderService;
    @Autowired
    private ProdSkuService prodSkuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserAddrService userAddrService;
    @Autowired
    private BasketService basketService;
    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 下单前预览订单信息
     * 传入下单所需要的参数进行下单
     */
    @PostMapping("/preSubmit")
    @Log(oper = "确认订单信息")
    public Result preSubmit(@Valid @RequestBody OrderParam orderParam) {
        String userId = TokenUtils.getLoginUserid();

        // 组装获取用户提交的购物车商品项
        List<ShopCartItemVo> shopCartItems = basketService.getShopCartItemsByOrderItems(orderParam.getBasketIds(), orderParam.getOrderItem(), userId);

        if (CollectionUtil.isEmpty(shopCartItems)) {
            throw new BusinessException("请选择您需要的商品加入购物车");
        }

        // 根据店铺组装购车中的商品信息，返回每个店铺中的购物车商品信息
        List<ShopCartVo> shopCarts = basketService.getShopCarts(shopCartItems);

        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerVo shopCartOrderMergerVo = new ShopCartOrderMergerVo();

        // 订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrCache(orderParam.getAddrId(), userId);
        UserAddrVo userAddrVo = BeanUtil.copyProperties(userAddr, UserAddrVo.class);
        shopCartOrderMergerVo.setUserAddr(userAddrVo);

        // 所有店铺的订单信息
        List<ShopCartOrderVo> shopCartOrders = new ArrayList<>();

        BigDecimal actualTotal = BigDecimal.ZERO;
        BigDecimal total = BigDecimal.ZERO;
        int totalCount = 0;
        BigDecimal orderReduce = BigDecimal.ZERO;
        for (ShopCartVo shopCart : shopCarts) {

            // 每个店铺的订单信息
            ShopCartOrderVo shopCartOrder = new ShopCartOrderVo();
            shopCartOrder.setShopId(shopCart.getShopId());
            shopCartOrder.setShopName(shopCart.getShopName());

            List<ShopCartItemDiscountVo> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();

            // 店铺中的所有商品项信息
            List<ShopCartItemVo> shopAllShopCartItems = new ArrayList<>();
            for (ShopCartItemDiscountVo shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemVo> discountShopCartItems = shopCartItemDiscount.getShopCartItems();
                shopAllShopCartItems.addAll(discountShopCartItems);
            }

            shopCartOrder.setShopCartItemDiscounts(shopCartItemDiscounts);

            applicationContext.publishEvent(new PreSubmitOrderEvent(shopCartOrder,orderParam,shopAllShopCartItems));

            actualTotal = NumberUtil.add(actualTotal,shopCartOrder.getActualTotal());
            total = NumberUtil.add(total,shopCartOrder.getTotal());
            totalCount = totalCount + shopCartOrder.getTotalCount();
            orderReduce = NumberUtil.add(orderReduce,shopCartOrder.getShopReduce());
            shopCartOrders.add(shopCartOrder);
        }

        shopCartOrderMergerVo.setActualTotal(actualTotal);
        shopCartOrderMergerVo.setTotal(total);
        shopCartOrderMergerVo.setTotalCount(totalCount);
        shopCartOrderMergerVo.setShopCartOrders(shopCartOrders);
        shopCartOrderMergerVo.setOrderReduce(orderReduce);
        shopCartOrderMergerVo = orderService.putConfirmOrderCache(userId, shopCartOrderMergerVo);

        return Result.ok(shopCartOrderMergerVo);
    }

    /**
     * 购物车/立即购买  提交订单,根据店铺拆单
     * 根据传入的参数判断是否为购物车提交订单，同时对购物车进行删除，用户开始进行支付
     */
    @PostMapping("/submit")
    @Log(oper = "提交订单")
    public Result submitOrders(@Valid @RequestBody SubmitOrderParam submitOrderParam) {
        String userId = TokenUtils.getLoginUserid();
        ShopCartOrderMergerVo mergerOrder = orderService.getConfirmOrderCache(userId);
        if (mergerOrder == null) {
            throw new BusinessException("订单已过期，请重新下单");
        }

        List<OrderShopParam> orderShopParams = submitOrderParam.getOrderShopParam();

        List<ShopCartOrderVo> shopCartOrders = mergerOrder.getShopCartOrders();
        // 设置备注
        if (CollectionUtil.isNotEmpty(orderShopParams)) {
            for (ShopCartOrderVo shopCartOrder : shopCartOrders) {
                for (OrderShopParam orderShopParam : orderShopParams) {
                    if (Objects.equals(shopCartOrder.getShopId(), orderShopParam.getShopId())) {
                        shopCartOrder.setRemarks(orderShopParam.getRemarks());
                    }
                }
            }
        }

        List<Order> orders = orderService.submit(userId,mergerOrder);

        StringBuilder orderNumbers = new StringBuilder();
        for (Order order : orders) {
            orderNumbers.append(order.getOrderNumber()).append(",");
        }
        orderNumbers.deleteCharAt(orderNumbers.length() - 1);

        boolean isShopCartOrder = false;
        // 移除缓存
        for (ShopCartOrderVo shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountVo shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemVo shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    String basketId = shopCartItem.getId();
                    if (StringUtils.isNotBlank(basketId) && !StringUtils.equals(basketId, "0")) {
                        isShopCartOrder = true;
                    }
                    prodSkuService.removeCacheBySkuId(shopCartItem.getSkuId(),shopCartItem.getProdId());
                    productService.removeProductCacheById(shopCartItem.getProdId());
                }
            }
        }
        // 购物车提交订单时(即有购物车ID时)
        if (isShopCartOrder) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        orderService.removeConfirmOrderCache(userId);
        return Result.ok(new OrderNumbersVo(orderNumbers.toString()));
    }
    
    @Log(oper = "获取订单支付信息")
	@GetMapping("/payInfo")
    public Result getOrderPayInfoByOrderNumber(@RequestParam("orderIds") String orderIds) {
    	
    	ValidateUtil.validRequired(orderIds, "订单号不能为空！");
    	
        List<String> orderIdList = StringUtils.str2List(orderIds);
        BigDecimal totalFee = BigDecimal.ZERO;
        String orderEndTime = null ;
        Order order ;
        for (String orderNo : orderIdList) {
        	order = orderService.selectSimpleByOrderNo(orderNo);
        	if(order == null) {
        		logger.error("获取订单支付信息时检查到订单不存在， orderNo：{}", orderNo);
        		throw new BusinessException("订单不存在！");
        	}
        	totalFee = NumberUtil.add(totalFee, order.getActualTotal());
        	orderEndTime = DateUtil.formatDateTime(order.getExpTime());
		}
        
        Map<String, Object> data = new HashMap<>();
        data.put("totalFee", totalFee);
        data.put("endTime", orderEndTime != null ? orderEndTime : DateUtil.getDurationDateStr(1));
        return Result.ok(data);
    }

}
